package com.link.base.core.basic.util.datax;

import com.link.core.cllog.LCLogger;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 生成存储过程代码的方法
 *
 * @author 何启谦
 * @date 2019/4/1
 */
public class DataxUtil {

    /**
     * 获取patter的过程较为负责,这里初始化时,做一次即可
     */
    private static final Pattern PATTERN = Pattern.compile("((?<=\\$\\{)([a-zA-Z_]{1,})(?=\\}))");

    /**
     * 字符串替换, 将 ${} 中的内容, 用给定的参数进行替换
     *
     * @param text
     * @param params
     * @return
     */
    public static String format(String text, Map<String, Object> params) {
        // 把文本中的所有需要替换的变量捞出来, 丢进keys
        Matcher matcher = PATTERN.matcher(text);
        while (matcher.find()) {
            String key = matcher.group();
            text = StringUtils.replace(text, "${" + key + "}", params.get(key) + "");
        }
        return text;
    }

    /**
     * 读取txt文件的内容
     *
     * @param file 想要读取的文件对象
     * @return 返回文件内容
     */
    private static String txt2String(File file) {
        StringBuilder result = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            //构造一个BufferedReader类来读取文件
//            BufferedReader br = new BufferedReader(new FileReader(file));
            String s = null;
            //使用readLine方法，一次读一行
            while ((s = br.readLine()) != null) {
                result.append(System.lineSeparator() + s);
            }
            br.close();
        } catch (Exception e) {
            LCLogger.withException(e);
        }
        return result.toString();
    }

    /**
     * 生成储存过程代码
     *
     * @param tempTablePrimaryKeyFieldName 临时表的主键名称
     * @param tempTableName                临时表名称
     * @param targetTableName              正式表名称
     * @param fieldList                    字段信息
     * @param fromPlatformFieldName        正式表的来源字段名称
     * @return
     */
    public static String createProcedureCode(String tempTablePrimaryKeyFieldName, String tempTableName, String targetTableName,
                                             List<FieldMapping> fieldList, String fromPlatformFieldName) {
        return createProcedureCode(tempTablePrimaryKeyFieldName, tempTableName, targetTableName,
                fieldList, fromPlatformFieldName, true);
    }

    /**
     * 生成储存过程代码
     *
     * @param tempTablePrimaryKeyFieldName 临时表的主键名称
     * @param tempTableName                临时表名称
     * @param targetTableName              正式表名称
     * @param fieldList                    字段信息
     * @param fromPlatformFieldName        正式表的来源字段名称
     * @param updateFlag                   是否支持update
     * @return
     */
    public static String createProcedureCode(String tempTablePrimaryKeyFieldName, String tempTableName, String targetTableName,
                                             List<FieldMapping> fieldList, String fromPlatformFieldName, boolean updateFlag) {
        // 提取update用到的字段
        List<FieldMapping> updateFieldList = new ArrayList<>();
        for (FieldMapping fieldInfo : fieldList) {
            if (!fieldInfo.isUpdateFlag()) {
                continue;
            }
            updateFieldList.add(fieldInfo);
        }

        String tempTableNameView = tempTableName;
        String viewSuffix = "_v";
        if (tempTableNameView.toLowerCase().endsWith(viewSuffix)) {
            tempTableName = tempTableName.substring(0, tempTableName.length() - viewSuffix.length());
        }

        String targetFromPlatform = "r_" + fromPlatformFieldName;

        // 生成 "局部变量的定义"代码
        StringBuilder declareVarsBuilder = new StringBuilder();
        for (int i = 0, len = fieldList.size(); i < len; i++) {
            FieldMapping fieldInfo = fieldList.get(i);
            if (i != 0) {
                declareVarsBuilder.append("    ");
            }
            declareVarsBuilder.append("DECLARE r_");
            declareVarsBuilder.append(fieldInfo.getTargetTableField());
            declareVarsBuilder.append(" ");
            declareVarsBuilder.append(fieldInfo.getFieldType());
            declareVarsBuilder.append(";");
            if (i < len - 1) {
                declareVarsBuilder.append("\n");
            }
        }

        StringBuilder tempFieldsBuilder = new StringBuilder();
        for (int i = 0, len = fieldList.size(); i < len; i++) {
            FieldMapping fieldInfo = fieldList.get(i);
            String tempTableField = fieldInfo.getTempTableField();
            if (i != 0) {
                tempFieldsBuilder.append("               ");
            }
            if (!tempTableField.contains(" ") && !tempTableField.contains("(") && !tempTableField.contains("'")) {
                tempFieldsBuilder.append("t1.");
            }
            tempFieldsBuilder.append(tempTableField);
            if (i < len - 1) {
                tempFieldsBuilder.append(",\n");
            }
        }

        //生成"遍历游标并赋值"的代码
        StringBuilder fetchIntoVarsBuilder = new StringBuilder();
        for (int i = 0, len = fieldList.size(); i < len; i++) {
            FieldMapping fieldInfo = fieldList.get(i);
            if (i != 0) {
                fetchIntoVarsBuilder.append("                    ");
            }
            fetchIntoVarsBuilder.append("r_");
            fetchIntoVarsBuilder.append(fieldInfo.getTargetTableField());
            if (i < len - 1) {
                fetchIntoVarsBuilder.append(",\n");
            }
        }

        // 生成"必输校验"的代码
        StringBuilder requiredBuilder = new StringBuilder();
        for (int i = 0, len = fieldList.size(); i < len; i++) {
            FieldMapping fieldInfo = fieldList.get(i);
            if (!fieldInfo.isRequired()) {
                continue;
            }

            if (StringUtils.isNotEmpty(requiredBuilder.toString())) {
                requiredBuilder.append("\n");
                requiredBuilder.append("\n");
                requiredBuilder.append("            ");
            }
            String targetTableField = fieldInfo.getTargetTableField();
            requiredBuilder.append("-- 校验" + targetTableField + "字段，不允许为空");
            requiredBuilder.append("\n");
            requiredBuilder.append("            if @r_" + targetTableField + " is null then");
            requiredBuilder.append("\n");
            requiredBuilder.append("                set x_fail_count = x_fail_count + 1;");
            requiredBuilder.append("\n");
            requiredBuilder.append("                -- 将错误信息记录到当前行的lc_extract_msg字段");
            requiredBuilder.append("\n");
            requiredBuilder.append("                set @lc_extract_flag = 'N';");
            requiredBuilder.append("\n");
            requiredBuilder.append("                set @lc_extract_msg = '" + targetTableField + "不能为空';");
            requiredBuilder.append("\n");
            requiredBuilder.append("                EXECUTE sql_extract_info_stmt USING @lc_extract_flag,@lc_extract_msg,@rx_integration_id;");
            requiredBuilder.append("\n");
            requiredBuilder.append("                -- 结束当次循环");
            requiredBuilder.append("\n");
            requiredBuilder.append("                iterate read_loop;");
            requiredBuilder.append("\n");
            requiredBuilder.append("            end if;");
        }

        // 生成"insert语句的字段"代码
        StringBuilder insertIntoTargetFieldBuilder = new StringBuilder();
        for (int i = 0, len = fieldList.size(); i < len; i++) {
            FieldMapping fieldInfo = fieldList.get(i);
            if (i != 0) {
                insertIntoTargetFieldBuilder.append("               ");
            }
            insertIntoTargetFieldBuilder.append(fieldInfo.getTargetTableField());
            if (i < len - 1) {
                insertIntoTargetFieldBuilder.append(",\n");
            }
        }

        // 生成insert语句的占位符(?)
        StringBuilder insertVarsPlaceholderBuilder = new StringBuilder();
        for (int i = 0, len = fieldList.size(); i < len; i++) {
            if (i != 0) {
                insertVarsPlaceholderBuilder.append("               ");
            }
            insertVarsPlaceholderBuilder.append("?");
            if (i < len - 1) {
                insertVarsPlaceholderBuilder.append(",\n");
            }
        }

        // 局部变量赋值用户变量
        StringBuilder localVarsToUserVarsBuilder = new StringBuilder();
        for (int i = 0, len = fieldList.size(); i < len; i++) {
            FieldMapping fieldInfo = fieldList.get(i);
            if (i != 0) {
                localVarsToUserVarsBuilder.append("                ");
            }
            localVarsToUserVarsBuilder.append("set @r_");
            localVarsToUserVarsBuilder.append(fieldInfo.getTargetTableField());
            localVarsToUserVarsBuilder.append(" = r_");
            localVarsToUserVarsBuilder.append(fieldInfo.getTargetTableField());
            localVarsToUserVarsBuilder.append(";\n");
        }


        // 执行insert时带上参数
        StringBuilder insertVarsVarsBuilder = new StringBuilder();
        for (int i = 0, len = fieldList.size(); i < len; i++) {
            FieldMapping fieldInfo = fieldList.get(i);
            if (i != 0) {
                insertVarsVarsBuilder.append("                        ");
            }
            insertVarsVarsBuilder.append("@r_");
            insertVarsVarsBuilder.append(fieldInfo.getTargetTableField());
            if (i < len - 1) {
                insertVarsVarsBuilder.append(",\n");
            }
        }

        // 执行update时带上参数
        StringBuilder updateVarsVarsBuilder = new StringBuilder();
        for (int i = 0, len = updateFieldList.size(); i < len; i++) {
            FieldMapping fieldInfo = updateFieldList.get(i);
            if (i != 0) {
                updateVarsVarsBuilder.append("                        ");
            }
            updateVarsVarsBuilder.append("@r_");
            updateVarsVarsBuilder.append(fieldInfo.getTargetTableField());
            if (i < len - 1) {
                updateVarsVarsBuilder.append(",\n");
            }
        }

        // 生成update语句项和占位符(?)
        StringBuilder updateTargetItem = new StringBuilder();
        for (int i = 0, len = updateFieldList.size(); i < len; i++) {
            FieldMapping fieldInfo = updateFieldList.get(i);
            if (i != 0) {
                updateTargetItem.append("                   ");
            }
            updateTargetItem.append(fieldInfo.getTargetTableField());
            updateTargetItem.append(" = ?");
            if (i < len - 1) {
                updateTargetItem.append(",\n");
            }
        }

        // 存储过程代码模板地址
        String folderPath = "D:\\Code\\jxbV1\\"
                + "jxb-linkcrm\\linkcrm-business\\src\\main\\java\\com\\hand\\business\\core\\basic\\util\\datax\\";
        String template = txt2String(new File(folderPath + "temp.txt"));

        Map<String, Object> params = new HashMap<>(16);
        params.put("targetFromPlatform", targetFromPlatform);
        params.put("tempTablePrimaryKeyFieldName", tempTablePrimaryKeyFieldName);
        params.put("tempTableName", tempTableName);
        params.put("tempTableNameView", tempTableNameView);
        params.put("targetTableName", targetTableName);
        params.put("fromPlatformFieldName", fromPlatformFieldName);
        params.put("declareVarsBuilder", declareVarsBuilder);
        params.put("tempFieldsBuilder", tempFieldsBuilder);
        params.put("fetchIntoVarsBuilder", fetchIntoVarsBuilder);
        params.put("requiredBuilder", requiredBuilder);
        params.put("insertVarsPlaceholderBuilder", insertVarsPlaceholderBuilder);
        params.put("localVarsToUserVarsBuilder", localVarsToUserVarsBuilder);
        params.put("insertVarsVarsBuilder", insertVarsVarsBuilder);
        params.put("updateVarsVarsBuilder", updateVarsVarsBuilder);
        params.put("insertIntoTargetFieldBuilder", insertIntoTargetFieldBuilder);
        params.put("updateTargetItem", updateTargetItem);
        if (updateFlag) {
            params.put("updateFlag_a", "");
            params.put("updateFlag_b", "");
        } else {
            params.put("updateFlag_a", "/* \n                -- 不允许update");
            params.put("updateFlag_b", "*/");
        }
        String result = format(template, params);
        return result;
    }

    public static void main(String[] args) {
//        String code = JiuGuanGou.prodTemp();
//        String code = JiuGuanGou.orderTemp();
//        String code = JiuGuanGou.orderItemTemp();
//        String code = JiuGuanGou.accntTemp();
//        String code = KaiGaiSaoMa.qrCodeTemp();
//        String code = KaiGaiSaoMa.couponsAccntTemp();
//        String code = KaiGaiSaoMa.wineReviewTemp();
//        String code = JxbMall.accntTemp();
//        String code = SiRenDingZhi.accntTemp();
//        String code = JustBattle.prodTemp();
//        String code = JustBattle.orderTemp();
//        String code = JustBattle.orderItemTemp();
//        String code = BiYeJi.userTemp();
//        String code = BiYeJi.signUpTemp();
//        String code = BiYeJi.accntCampMonitorTemp();
//        String code = BiYeJi.giftRecordTemp();
//        String code = BiYeJi.giftRecordTemp();
//        String code = BiYeJi.photoTemp();
//        String code = YeWuZhongTai.orderTemp();
//        String code = YeWuZhongTai.orderItemTemp();
//        String code = YeWuZhongTai.returnOrderTemp();
//        String code = YeWuZhongTai.returnProdTemp();
        //String code = YeWuZhongTai.exchangeProdTemp();
       // String code = YeWuZhongTai.returnJxbProdTmp();
        //String code = YeWuZhongTai.returnJxbWideProdTmp();
       // String code = YeWuZhongTai.returnJxbLegalEntityTmp();
       //String code = YeWuZhongTai.returnJxbBrandTmp();
        //String code = YeWuZhongTai.returnJxbBrandCategoryTmp();
        String code = YeWuZhongTai.returnJxbOrderAddrTmp();

        System.out.println(code);
    }
}
